package com.example.pvlib.pathView;

import com.example.pvlib.ResourceTable;
import com.example.pvlib.pathView.Animator.AnimatorBuilder;
import com.example.pvlib.pathView.Animator.AnimatorSetBuilder;
import com.example.pvlib.svgloadHm.SVG;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.ResourceManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Position;
import ohos.media.image.common.Size;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PathView extends Image implements Component.DrawTask {


    public static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
    /**
     * Logging tag.
     */
    public static final String LOG_TAG = "PathView";
    /**
     * The paint for the path.
     */
    //----李
    //private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint paint;
    private boolean isfirst = true;


    {
        paint = new Paint();
        paint.setAntiAlias(true);
    }

    /**
     * Utils to catch the paths from the svg.
     */
    public final SvgUtils svgUtils = new SvgUtils(paint);
    /**
     * All the paths provided to the view. Both from Path and Svg.
     */
    public List<SvgUtils.SvgPath> paths = new ArrayList<>();
    /**
     * This is a lock before the view is redrawn
     * or resided it must be synchronized with this object.
     */
    private final Object mSvgLock = new Object();
    /**
     * Thread for working with the object above.
     */
    private Thread mLoader;

    /**
     * The svg image from the raw directory.
     */
    private String svgResourceId="";
    /**
     * Object that builds the animation for the path.
     */
    private AnimatorBuilder animatorBuilder;
    /**
     * Object that builds the animation set for the path.
     */
    private AnimatorSetBuilder animatorSetBuilder;
    /**
     * The progress of the drawing.
     */
    private float progress = 0f;

    /**
     * If the used colors are from the svg or from the set color.
     */
    private boolean naturalColors;
    /**
     * If the view is filled with its natural colors after path drawing.
     */
    private boolean fillAfter;
    /**
     * The view will be filled and showed as default without any animation.
     */
    private boolean fill;
    /**
     * The solid color used for filling svg when fill is true
     */
    private int fillColor;
    /**
     * The width of the view.
     */
    private int width;
    /**
     * The height of the view.
     */
    private int height;
    /**
     * Will be used as a temporary surface in each onDraw call for more control over content are
     * drawing.
     */
    private PixelMap mTempBitmap;
    /**
     * Will be used as a temporary Canvas for mTempBitmap for drawing content on it.
     */
    private Canvas mTempCanvas;
    public static SVG svg;

    EventHandler eventHandler = new EventHandler(EventRunner.getMainEventRunner()) {

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
        /*    Picture picture=svg.getPicture();
         PixelMap.InitializationOptions options=new PixelMap.InitializationOptions();
         options.size=new Size(picture.getWidth(),picture.getHeight());
        backPixMap=PixelMap.create(options);
            Texture texture=new Texture(backPixMap);
            canvas=new Canvas(texture);
            canvas.drawPicture(picture);
            pathViewDemo.setPixelMap(backPixMap);*/
            invalidate();

        }
    };


    private void loadSvg() {
      /*  new Thread()
        {
            @Override
            public void run() {

                super.run();
                try {
                    svgBuilder.readFromInputStream(getResourceManager().getRawFileEntry("resources/rawfile/monitor.xml").openRawFile());
                    svg= svgBuilder.build();
                    if (svg!=null)
                    { InnerEvent event=InnerEvent.get(1);
                        eventHandler.sendEvent(event);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();*/
        if (mLoader != null) {
            try {
                mLoader.join();
            } catch (InterruptedException e) {
                //  Log.e(LOG_TAG, "Unexpected error", e);
            }
        }
        if (svgResourceId!="") {
            mLoader = new Thread(new Runnable() {
                @Override
                public void run() {

                    try {
                        svgUtils.load(getResourceManager().getRawFileEntry(svgResourceId).openRawFile());
                        //  ToastUtil.makeToast(getContext(),svgUtils.mSvg.getPath().size()+"");
                        eventHandler.sendEvent(InnerEvent.get());
                    } catch (IOException e) {
                        HiLog.error(LABEL,"PathView", e);
                    }

                 /*   synchronized (mSvgLock) {
                        width = getWidth() - getPaddingLeft() - getPaddingRight();
                        height = getHeight() - getPaddingTop() - getPaddingBottom();
                        paths = svgUtils.getPathsForViewport(width, height);
                        updatePathsPhaseLocked();
                    }*/
                }
            }, "SVG Loader");
            mLoader.start();
        }
    }

    private void updatePathsPhaseLocked() {
        final int count = paths.size();
        for (int i = 0; i < count; i++) {
            SvgUtils.SvgPath svgPath = paths.get(i);
            svgPath.path.reset();
            svgPath.measure.getSegment(0.0f, svgPath.length * progress, svgPath.path, true);
            svgPath.path.rLineTo(0.0f, 0.0f);
        }
    }

    private void init() {
        ResourceManager resourceManager = getResourceManager();
        Color color = new Color(ResourceTable.Color_deflatePathColor);
        int pathWidth = 2;
        naturalColors = false;
        fill = false;
        fillColor = Color.argb(0, 0, 0, 0);
        // paint.setColor(color);
        paint.setColor(Color.WHITE);
        paint.setStrokeWidth(pathWidth);
        paint.setStyle(Paint.Style.STROKE_STYLE);
        addDrawTask(this);
        //invalidate();
        if (svgResourceId!="")
        loadSvg();

    }

    public PathView(Context context) {
        super(context);
        init();
    }

    public PathView(Context context, AttrSet attrSet) {
        this(context);

    }

    public PathView(Context context, AttrSet attrSet, String styleName) {
        this(context, attrSet);

    }

    @Override
    public void onDraw(Component component, Canvas canvas) {


/*
        if (!isfirst) {

            paths = svgUtils.getPathsForViewport(getWidth(), getHeight());
            for (int i = 0; i < paths.size(); i++) {
                final SvgUtils.SvgPath svgPath = paths.get(i);
                final Path path = svgPath.path;
                final Paint paint1 = naturalColors ? svgPath.paint : paint;
                canvas.drawPath(path, paint1);

                //       svgUtils.drawSvgAfter(canvas,getWidth(),getHeight());

            }

        }
*/
//--------------------------
        synchronized (mSvgLock) {
            if (svgUtils.mSvg != null) {
                if (isfirst) {
                    width=getWidth();
                    height=getHeight();
                    isfirst = false;
                    paths = svgUtils.getPathsForViewport(getWidth(), getHeight());
                    // ToastUtil.makeToast(getContext(),paths.size()+"");
                     updatePathsPhaseLocked();
                }

                if (mTempBitmap == null || (mTempBitmap.getImageInfo().size.width != getWidth() || mTempBitmap.getImageInfo().size.height != getHeight())) {
                    //   mTempBitmap = PixelMap.create(canvas.getWidth(), canvas.getHeight(),  new PixelMap.InitializationOptions().);
                    //     int[] defaultColors = new int[] {5, 5, 5, 5, 6, 6, 3, 3, 3, 0};
                    PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
                    //  initializationOptions.size = new Size(3, 2);
                    initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
                    // initializationOptions.editable = true;
                    initializationOptions.size = new Size(getWidth(), getHeight());
                    mTempBitmap = PixelMap.create(initializationOptions);
                    Texture texture = new Texture(mTempBitmap);
                    mTempCanvas = new Canvas(texture);

                }

                // mTempBitmap.eraseColor(0);
                // mTempBitmap= mTempBitmap.createFromAlpha();

                //   synchronized (mSvgLock) {
                HiLog.info(LABEL, "LAJIHM");
                mTempCanvas.save();
                mTempCanvas.translate(getPaddingLeft(), getPaddingTop());
                fill(mTempCanvas);
                mTempCanvas.restore();
                final int count = paths.size();
                HiLog.info(LABEL, "LAJIHM");
                HiLog.info(LABEL, count + "");
                for (int i = 0; i < count; i++) {
                    final SvgUtils.SvgPath svgPath = paths.get(i);
                    final Path path = svgPath.path;
                    final Paint paint1 = naturalColors ? svgPath.paint : paint;
                    mTempCanvas.drawPath(path, paint1);
                }
                mTempCanvas.save();
                fillAfter(mTempCanvas);

                mTempCanvas.restore();

                applySolidColor(mTempBitmap);

                // canvas.drawBitmap(mTempBitmap,0,0,null);
                PixelMapHolder pixelMapHolder = new PixelMapHolder(mTempBitmap);
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.FILL_STYLE);
                canvas.drawPixelMapHolder(pixelMapHolder, 0, 0, paint);
            }
        }
    }

    private void applySolidColor(final PixelMap bitmap) {
        Size size = bitmap.getImageInfo().size;
        if ((fill && fillColor != Color.argb(0, 0, 0, 0)) && (bitmap != null))
                for (int x = 0; x < size.width; x++) {
                    for (int y = 0; y < size.height; y++) {
                        int argb = bitmap.readPixel(new Position(x, y));
                        int alpha = Color.alpha(argb);
                        if (alpha != 0) {
                           /* int red = Color.red(fillColor);
                            int green = Color.green(fillColor);
                            int blue =  Color.blue(fillColor);*/
                            RgbColor rgbColor = new RgbColor(fillColor);
                            int red = rgbColor.getRed();
                            int green = rgbColor.getGreen();
                            int blue = rgbColor.getBlue();
                            argb = Color.argb(alpha, red, green, blue);
                            bitmap.writePixel(new Position(x, y), argb);
                        }
                    }
                }

    }

    private void fillAfter(final Canvas canvas) {
        if (svgResourceId != "" && fillAfter && Math.abs(progress - 1f) < 0.00000001) {
            svgUtils.drawSvgAfter(canvas, width, height);
        }
    }

    /**
     * If there is svg , the user called setFill(true).
     *
     * @param canvas Draw to this canvas.
     */
    private void fill(final Canvas canvas) {
        if (svgResourceId != "" && fill) {
            svgUtils.drawSvgAfter(canvas, width, height);
        }
    }

    public void setPaths(List<Path> paths) {
        for (Path path : paths) {
            this.paths.add(new SvgUtils.SvgPath(path, paint));
        }
        synchronized (mSvgLock) {
            updatePathsPhaseLocked();
        }
    }


    public void setPath(Path path) {
        paths.add(new SvgUtils.SvgPath(path, paint));
        synchronized (mSvgLock) {
            updatePathsPhaseLocked();
        }
    }

    public void setPercentage(float percentage) {
        if (percentage < 0.0f || percentage > 1.0f) {
            throw new IllegalArgumentException("setPercentage not between 0.0f and 1.0f");
        }
        progress = percentage;
        synchronized (mSvgLock) {
                     updatePathsPhaseLocked();
        }
        invalidate();
    }


    public AnimatorBuilder getPathAnimator() {
        if (animatorBuilder == null) {
            animatorBuilder = new AnimatorBuilder(this);
        }
        return animatorBuilder;
    }


    public AnimatorSetBuilder getSequentialPathAnimator() {
        if (animatorSetBuilder == null) {
            animatorSetBuilder = new AnimatorSetBuilder(this);
        }
        return animatorSetBuilder;
    }


    public void useNaturalColors() {
        naturalColors = true;
    }


    public void setFillColor(int color) {
        this.fillColor = color;
    }


    public void setFillAfter(boolean fillAfter) {
        this.fillAfter = fillAfter;
    }


    public void setFill(boolean fill) {
        this.fill = fill;
    }


    public int getPathColor() {
        return paint.getColor().getValue();
    }


    public void setPathColor(int color) {
        paint.setColor(new Color(color));
    }


    public float getPathWidth() {
        return paint.getStrokeWidth();
    }


    public void setPathWidth(float width) {
        paint.setStrokeWidth(width);
    }


    public String getSvgResource() {
        return svgResourceId;
    }


    public void setSvgResource(String svgResource) {
        svgResourceId = svgResource;
        loadSvg();
    }


}
